#include <auto_ptr.h>
#include <gtest/gtest.h>
#include "../storage/storage.h"
#include <utility>
#include "../md5/md5.h"
using namespace utils;
class FileObjectTestBase : public ::testing::TestWithParam<const char*>
{
protected:
    std::auto_ptr<storagemon::IFile> m_file;
    char md5[MD5_DIGEST_SIZE];
};

class FileObjectTestBaseUL : public ::testing::TestWithParam<u_long>
{
protected:
    std::auto_ptr<storagemon::IFile> m_file;
    char md5[MD5_DIGEST_SIZE];
};

class FileObjectTestName : public FileObjectTestBase
{
protected:
    void SetUp()
    {
        memcpy((void*)md5,
            (void*)"o\215\265\231\336\230o\253z!b[y\026X\234",
            MD5_DIGEST_SIZE);
        m_file.reset(new storagemon::FileObject(
                "/home/test",
                GetParam(),
                md5,
                0,
                0));
    }
};

class FileObjectTestPath : public FileObjectTestBase
{
protected:
    void SetUp()
    {
        memcpy((void*)md5,
            (void*)"o\215\265\231\336\230o\253z!b[y\026X\234",
            MD5_DIGEST_SIZE);
        m_file.reset(new storagemon::FileObject(
                GetParam(),
                "test.txt",
                md5,
                0,
                0));
    }
};

class FileObjectTestID : public FileObjectTestBaseUL
{
protected:
    void SetUp()
    {
        memcpy((void*)md5,
            (void*)"o\215\265\231\336\230o\253z!b[y\026X\234",
            MD5_DIGEST_SIZE);
        m_file.reset(new storagemon::FileObject(
                "/home/test",
                "test.txt",
                md5,
                GetParam(),
                0));
    }
};

class FileObjectTestParentID : public FileObjectTestBaseUL
{
protected:
    void SetUp()
    {
        memcpy((void*)md5,
            (void*)"o\215\265\231\336\230o\253z!b[y\026X\234",
            MD5_DIGEST_SIZE);
        m_file.reset(new storagemon::FileObject(
                "/home/test",
                "test.txt",
                md5,
                0,
                GetParam()));
    }
};

class FileObjectTestMD5 : public FileObjectTestBase
{
protected:
    void SetUp()
    {
        memcpy((void*)md5,
            (void*)"o\215\265\231\336\230o\253z!b[y\026X\234",
            MD5_DIGEST_SIZE);
        m_file.reset(new storagemon::FileObject(
                "/home/test",
                "test.txt",
                md5,
                0,
                0));
    }
};

TEST_P(FileObjectTestName, Name)
{
    EXPECT_STREQ(GetParam(), m_file->name());
}
/*
TEST_P(FileObjectTestName, FullPath)
{
    std::string fp;
    fp.append("/home/test//").append(GetParam());
    EXPECT_STREQ(fp.c_str(), m_file->full_path());
}
 */

TEST_P(FileObjectTestPath, Path)
{
    EXPECT_STREQ(GetParam(), m_file->path());
}

TEST_P(FileObjectTestPath, FullPath)
{
    std::string fp;
    fp.append(GetParam()).append("/test.txt");
    EXPECT_STREQ(fp.c_str(), m_file->full_path());
}

TEST_P(FileObjectTestID, ID)
{
    EXPECT_EQ(GetParam(), m_file->id());
}

TEST_P(FileObjectTestParentID, Parent_ID)
{
    EXPECT_EQ(GetParam(), m_file->parent_id());
}

TEST_P(FileObjectTestMD5, md5_check)
{
    char res[MD5_BLOCK_SIZE];
    md5_to_string(m_file->md5(), res);
    EXPECT_STREQ(GetParam(), res);
}


INSTANTIATE_TEST_CASE_P(FileInterface,
                        FileObjectTestName,
                        ::testing::Values("test1.txt",
                        "test2.txt",
                        "",
                        "abracadabra",
                        "03a4sd65asd"));

INSTANTIATE_TEST_CASE_P(FileInterface,
                        FileObjectTestPath,
                        ::testing::Values("",
                        "/",
                        "/home",
                        "abracadabra"));

INSTANTIATE_TEST_CASE_P(FileInterface,
                        FileObjectTestID,
                        ::testing::Range((u_long)0,
                            (u_long)4294967295,
                            (u_long)429496729));

INSTANTIATE_TEST_CASE_P(FileInterface,
                        FileObjectTestParentID,
                        ::testing::Range((u_long)0,
                            (u_long)4294967295,
                            (u_long)429496729));

INSTANTIATE_TEST_CASE_P(FileInterface,
                        FileObjectTestMD5,
                        ::testing::Values("6f8db599de986fab7a21625b7916589c"));